#include"Timer.h"
#include"DealConn.h"

std::atomic_flag Timer::lock = ATOMIC_FLAG_INIT;  
std::priority_queue<ELM, std::vector<ELM>,
		    bool(*)(const ELM &, const ELM &)> Timer::minHeap(cmp);
std::function<void(const int &)> Timer::worker = DealConn::closeConn;
std::chrono::duration<int> Timer::checkSpan;
std::chrono::duration<int> Timer::minSpan;

Timer::Timer(int min){
  minSpan = std::chrono::seconds(min);
  lock.clear();
  std::thread(check).detach();
}

bool Timer::cmp(const ELM &a, const ELM &b){
  return a.first < b.first;
}
  
void Timer::addTask(int t, time_point &time){
  while(lock.test_and_set()) std::this_thread::yield();
  minHeap.push({time, t});
  lock.clear();
}

void Timer::check(){
  while(true){
    while(lock.test_and_set()) std::this_thread::yield();
    auto &&now = std::chrono::system_clock::now();
    while(!minHeap.empty()){
      auto &t = minHeap.top();
      minHeap.pop();
      worker(t.second);
      if(t.first > now){
	checkSpan = std::chrono::duration_cast<std::chrono::seconds>(t.first - now);
	break;
      }
    }
    lock.clear();
    std::this_thread::sleep_for((checkSpan > minSpan ? checkSpan : minSpan));
  }
}
